package com.forage.exp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.forage.exp.constant.ResponseStatusEnum;
import com.forage.exp.mapper.UserMapper;
import com.forage.exp.po.GlobalException;
import com.forage.exp.po.Response;
import com.forage.exp.po.User;
import com.forage.exp.po.UserAuthority;
import com.forage.exp.service.UserService;
import com.forage.exp.utils.JwtUtils;
import com.forage.exp.utils.RedisCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author : George
 * @date : 2022-05-3
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Override
    public Response login(User user) {
        //AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUserAccount(),user.getUserPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);

        if(Objects.isNull(authenticate)){
            //如果认证没通过，给出对应的提示（保险措施，一般异常不从这里抛出）
            throw new RuntimeException("用户名或者密码错误");
//            throw new GlobalException(ResponseStatusEnum.AUTHENTICATION_EXCEPTION, "用户名或者密码错误");
        }

        //把完整的用户信息存入redis，userid作为key
        UserAuthority userAuthority = (UserAuthority) authenticate.getPrincipal();
        String userId = userAuthority.getUser().getUserId().toString();
        redisCache.setCacheObject("login:"+userId, userAuthority,3, TimeUnit.HOURS);

        //使用 userId 生成一个 JWT 返回
        return new Response().setStatus(ResponseStatusEnum.OK)
                .addData("token",JwtUtils.createJWT(userId))
                .addData("userAccount",userAuthority.getUser().getUserAccount());
    }

    @Override
    public Response getOneByUserAccount(String userAccount) {
        User user = this.baseMapper.selectOne(new QueryWrapper<User>()
                .eq("user_account", userAccount));
        return new Response().setStatus(ResponseStatusEnum.OK)
                .setData(user);

    }

    @Override
    public Response getOneByUserId(Integer userId) {
        User user = this.baseMapper.selectOne(new QueryWrapper<User>()
                .eq("user_id", userId));
        return new Response().setStatus(ResponseStatusEnum.OK)
                .setData(user);
    }
}
